<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>class SyntaxSuggest::BlockExpand - syntax_suggest: Ruby Standard Library Documentation</title>


<script src="../js/navigation.js" defer></script>
<script src="../js/search.js" defer></script>
<script src="../js/search_index.js" defer></script>
<script src="../js/searcher.js" defer></script>
<script src="../js/darkfish.js" defer></script>

<script src="../js/jquery-3.2.0.min.js"></script>

<script src="../js/vue.min.js"></script>
<script src="../js/js.cookie.min.js"></script>

<link href="../css/fonts.css" rel="stylesheet">
<link id='rdoccss' href="../css/rdoc.css" rel="stylesheet">
<link href="../css/carbon17.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "../";
  var index_rel_prefix = "../";
  var darkModeCsseHref = "../css/rdoc-dm.css"
  var defaultModeCssHref = "../css/rdoc.css"
  // var cssDarkmode = Cookies.get('darkmode');
  
  if( Cookies.get("darkmode") == "true") {
	$('#rdoccss').attr("href", darkModeCsseHref);
}

//  https://cssdeck.com/blog/simple-jquery-stylesheet-switcher/

document.write('<style type="text/css">body{display:none}</style>');

</script>


</head>
<body id="top" role="document" class="class">
  <!-- this is class.html -->

  <div id='actionbar' >
    <div class='wrapper mdiv'>
      <ul class='grids g0'></ul>
    </div> 
    <!-- VERSION HEADER for 3.3.0.preview2 NOT FOUND -->
  </div> <!-- end action bar -->

  <div class='wrapper hdiv'>

    


    <nav id='vapp' role="navigation">
    <div id="project-navigation">
      <div id="home-section" role="region" title="Quick navigation" class="nav-section">
  <h2><a href="../index.html" rel="home">Home</a></h2>

  <div id="table-of-contents-navigation"  >
    <a href="../table_of_contents.html#pages">Pages</a>
    <a href="../table_of_contents.html#classes">Classes</a>
    <a href="../table_of_contents.html#methods">Methods</a>
  </div>
</div>

      <div id="search-section" role="search" class="project-section initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <div id="search-field-wrapper">
      <input id="search-field" role="combobox" aria-label="Search"
             aria-autocomplete="list" aria-controls="search-results"
             type="text" name="search" placeholder="Search" spellcheck="false"
             title="Type to search, Up and Down to navigate, Enter to load">
    </div>

    <ul id="search-results" aria-label="Search Results"
        aria-busy="false" aria-expanded="false"
        aria-atomic="false" class="initially-hidden"></ul>
  </form>
</div>

    </div>


    

    <button id='toggleThing' @click="toggleNav()" >Show/hide navigation</button>
    <div :class="isOpen ? 'block' : 'hidden' " id='toggleMe'>
      <div id="class-metadata">
        
        
<div id="parent-class-section" class="nav-section">
  <h3>Parent</h3>

  <p class="link">Object
</div>

        
        
        
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
  <h3>Methods</h3>

  <ul class="link-list" role="directory">
    <li ><a href="#method-c-new">::new</a>
    <li ><a href="#method-i-call">#call</a>
    <li ><a href="#method-i-expand_indent">#expand_indent</a>
    <li ><a href="#method-i-expand_neighbors">#expand_neighbors</a>
    <li ><a href="#method-i-inspect">#inspect</a>
  </ul>
</div>

      </div>
     </div>
    </nav>


    <div id='extraz'><div class='adzbox-index'  >
      
     </div>         
    </div>

    <main role="main" aria-labelledby="class-SyntaxSuggest::BlockExpand">
    <h1 id="class-SyntaxSuggest::BlockExpand" class="class">
      class SyntaxSuggest::BlockExpand
    </h1>

    <section class="description">
    
<p>This class is responsible for taking a code block that exists at a far indentaion and then iteratively increasing the block so that it captures everything within the same indentation block.</p>

<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">dog</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;bow&quot;</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;wow&quot;</span>
<span class="ruby-keyword">end</span>
</pre>

<p>block = <a href="BlockExpand.html#method-c-new"><code>BlockExpand.new</code></a>(code_lines: code_lines)</p>

<pre>.call(CodeBlock.new(lines: code_lines[1]))</pre>

<p>puts block.to_s # =&gt; puts “bow”</p>

<pre class="ruby"><span class="ruby-identifier">puts</span> <span class="ruby-string">&quot;wow&quot;</span>
</pre>

<p>Once a code block has captured everything at a given indentation level then it will expand to capture surrounding indentation.</p>

<p>block = <a href="BlockExpand.html#method-c-new"><code>BlockExpand.new</code></a>(code_lines: code_lines)</p>

<pre>.call(block)</pre>

<p>block.to_s # =&gt; def dog</p>

<pre>  puts &quot;bow&quot;
  puts &quot;wow&quot;
end</pre>

    </section>

      <section id="5Buntitled-5D" class="documentation-section">





                <section id="public-class-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Class Methods</h3>
                </header>

                  <div id="method-c-new" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">new</span><span
                                class="method-args">(code_lines:)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="new-source">
            <pre><span class="ruby-comment"># File syntax_suggest/block_expand.rb, line 34</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">initialize</span>(<span class="ruby-value">code_lines:</span>)
  <span class="ruby-ivar">@code_lines</span> = <span class="ruby-identifier">code_lines</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                          </section>

                <section id="public-instance-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Instance Methods</h3>
                </header>

                  <div id="method-i-call" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">call</span><span
                                class="method-args">(block)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Main interface. Expand current indentation, before expanding to a lower indentation</p>

                              <div class="method-source-code" id="call-source">
            <pre><span class="ruby-comment"># File syntax_suggest/block_expand.rb, line 40</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">call</span>(<span class="ruby-identifier">block</span>)
  <span class="ruby-keyword">if</span> (<span class="ruby-identifier">next_block</span> = <span class="ruby-identifier">expand_neighbors</span>(<span class="ruby-identifier">block</span>))
    <span class="ruby-identifier">next_block</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-identifier">expand_indent</span>(<span class="ruby-identifier">block</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-expand_indent" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">expand_indent</span><span
                                class="method-args">(block)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Expands code to the next lowest indentation</p>

<p>For example:</p>

<pre>1 def dog
2   print &quot;dog&quot;
3 end</pre>

<p>If a block starts on line 2 then it has captured all it’s “neighbors” (code at the same indentation or higher). To continue expanding, this block must capture lines one and three which are at a different indentation level.</p>

<p>This method allows fully expanded blocks to decrease their indentation level (so they can expand to capture more code up and down). It does this conservatively as there’s no undo (currently).</p>

                              <div class="method-source-code" id="expand_indent-source">
            <pre><span class="ruby-comment"># File syntax_suggest/block_expand.rb, line 63</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">expand_indent</span>(<span class="ruby-identifier">block</span>)
  <span class="ruby-identifier">now</span> = <span class="ruby-constant">AroundBlockScan</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">code_lines:</span> <span class="ruby-ivar">@code_lines</span>, <span class="ruby-value">block:</span> <span class="ruby-identifier">block</span>)
    .<span class="ruby-identifier">force_add_hidden</span>
    .<span class="ruby-identifier">stop_after_kw</span>
    .<span class="ruby-identifier">scan_adjacent_indent</span>

  <span class="ruby-identifier">now</span>.<span class="ruby-identifier">lookahead_balance_one_line</span>

  <span class="ruby-identifier">now</span>.<span class="ruby-identifier">code_block</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-expand_neighbors" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">expand_neighbors</span><span
                                class="method-args">(block)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>A neighbor is code that is at or above the current indent line.</p>

<p>First we build a block with all neighbors. If we can’t go further then we decrease the indentation threshold and expand via indentation i.e. ‘expand_indent`</p>

<p>Handles two general cases.</p>

<p>## Case #1: Check code inside of methods/classes/etc.</p>

<p>It’s important to note, that not everything in a given indentation level can be parsed as valid code even if it’s part of valid code. For example:</p>

<pre>1 hash = {
2   name: &quot;richard&quot;,
3   dog: &quot;cinco&quot;,
4 }</pre>

<p>In this case lines 2 and 3 will be neighbors, but they’re invalid until ‘expand_indent` is called on them.</p>

<p>When we are adding code within a method or class (at the same indentation level), use the empty lines to denote the programmer intended logical chunks. Stop and check each one. For example:</p>

<pre>1 def dog
2   print &quot;dog&quot;
3
4   hash = {
5 end</pre>

<p>If we did not stop parsing at empty newlines then the block might mistakenly grab all the contents (lines 2, 3, and 4) and report them as being problems, instead of only line 4.</p>

<p>## Case #2: Expand/grab other logical blocks</p>

<p>Once the search algorithm has converted all lines into blocks at a given indentation it will then ‘expand_indent`. Once the blocks that generates are expanded as neighbors we then begin seeing neighbors being other logical blocks i.e. a block’s neighbors may be another method or class (something with keywords/ends).</p>

<p>For example:</p>

<pre>1 def bark
2
3 end
4
5 def sit
6 end</pre>

<p>In this case if lines 4, 5, and 6 are in a block when it tries to expand neighbors it will expand up. If it stops after line 2 or 3 it may cause problems since there’s a valid kw/end pair, but the block will be checked without it.</p>

<p>We try to resolve this edge case with ‘lookahead_balance_one_line` below.</p>

                              <div class="method-source-code" id="expand_neighbors-source">
            <pre><span class="ruby-comment"># File syntax_suggest/block_expand.rb, line 130</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">expand_neighbors</span>(<span class="ruby-identifier">block</span>)
  <span class="ruby-identifier">now</span> = <span class="ruby-constant">AroundBlockScan</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">code_lines:</span> <span class="ruby-ivar">@code_lines</span>, <span class="ruby-value">block:</span> <span class="ruby-identifier">block</span>)

  <span class="ruby-comment"># Initial scan</span>
  <span class="ruby-identifier">now</span>
    .<span class="ruby-identifier">force_add_hidden</span>
    .<span class="ruby-identifier">stop_after_kw</span>
    .<span class="ruby-identifier">scan_neighbors_not_empty</span>

  <span class="ruby-comment"># Slurp up empties</span>
  <span class="ruby-identifier">now</span>
    .<span class="ruby-identifier">scan_while</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">line</span><span class="ruby-operator">|</span> <span class="ruby-identifier">line</span>.<span class="ruby-identifier">empty?</span> }

  <span class="ruby-comment"># If next line is kw and it will balance us, take it</span>
  <span class="ruby-identifier">expanded_lines</span> = <span class="ruby-identifier">now</span>
    .<span class="ruby-identifier">lookahead_balance_one_line</span>
    .<span class="ruby-identifier">lines</span>

  <span class="ruby-comment"># Don&#39;t allocate a block if it won&#39;t be used</span>
  <span class="ruby-comment">#</span>
  <span class="ruby-comment"># If nothing was taken, return nil to indicate that status</span>
  <span class="ruby-comment"># used in `def call` to determine if</span>
  <span class="ruby-comment"># we need to expand up/out (`expand_indent`)</span>
  <span class="ruby-keyword">if</span> <span class="ruby-identifier">block</span>.<span class="ruby-identifier">lines</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">expanded_lines</span>
    <span class="ruby-keyword">nil</span>
  <span class="ruby-keyword">else</span>
    <span class="ruby-constant">CodeBlock</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">lines:</span> <span class="ruby-identifier">expanded_lines</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-inspect" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">inspect</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Managable rspec errors</p>

                              <div class="method-source-code" id="inspect-source">
            <pre><span class="ruby-comment"># File syntax_suggest/block_expand.rb, line 161</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">inspect</span>
  <span class="ruby-string">&quot;#&lt;SyntaxSuggest::CodeBlock:0x0000123843lol &gt;&quot;</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                          </section>

              </section>
              </main>



            </div>  <!--  class='wrapper hdiv' -->


<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a></p>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.4.0.</p>
<p>Based on <a href="https://github.com/ged/darkfish/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.</p>

  
    <p><p><a href="https://ruby-doc.org">Ruby-doc.org</a> is provided by <a href="https://jamesbritt.com">James Britt</a> and <a href="https://neurogami.com">Neurogami</a>. </p><p><a href="https://jamesbritt.bandcamp.com/">Hack your world.  Feed your head.  Live curious</a>.</p>
</p>
  
  </footer>

<script type="text/javascript">


  let ads  = $("#carbonads-container").children().detach();


  function swapMode() {
    var cookieName = 'darkmode';
    var cssDarkmode = Cookies.get(cookieName);
    console.log("***** swapMode! " + cssDarkmode + " *****");


    if (cssDarkmode == "true") {
      console.log("We have dark mode, set the css to light ...");
      $('#rdoccss').attr("href", defaultModeCssHref);
      $('#cssSelect').text("Dark mode");
      cssDarkmode = "false";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    } else {
      console.log("We not have dark mode, set the css to dark ...");
      $('#rdoccss').attr("href", darkModeCsseHref);
      $('#cssSelect').text("Light mode");
      cssDarkmode = "true";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    }

    console.log("  --------------- ");
  }


const vueCssApp = new Vue({
el: '#menubar',
data: {
isDark: false
},
methods: {
toggleClass: function(event){
this.isDark = !this.isDark;
}
}
})

const vueApp = new Vue({
el: '#vapp',
data: { 
isOpen: true
},

mounted() {
this.handleResize();
this.manage_mob_classes();
window.addEventListener('resize', this.handleResize)
//this.isOpen !=  (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
created() {
//manage_mob_classes();
},

methods : {
isMobile() {
  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},

  handleResize() {
    if (!this.isMobile()) {
      this.isOpen = window.innerWidth > 800;
    }
  },

  manage_mob_classes() {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
      $("nav").addClass("mob_nav");
      $("main").addClass("mob_main");
      $("#extraz").addClass("mob_extraz");
      $("#carbonads-container").addClass("mob_carbonads-container");
      this.isOpen  = false;
    } else {
      $("nav").removeClass("mob_nav") 
        $("main").removeClass("mob_main");
      $("#extraz").removeClass("mob_extraz");
      $("#carbonads-container").removeClass("mob_carbonads-container");
      this.isOpen  = true;
    }
  },

  toggleNav() {
    this.isOpen =! this.isOpen ;
    // alert("Toggle nav!");
    console.log("toggleNav() click: " + this.isOpen );
  }
}
})

$("#carbonads-container").append(ads);


$(function() {

    var darkmode = Cookies.get("darkmode");
    console.log("Document ready: " + darkmode);

    if ( darkmode  == "true" ) {
      $('#cssSelect').text("Light mode");
    } else {
      $('#cssSelect').text("Dark mode");
     }

    $('body').css('display','block');
    });

</script>

    
  </body> 
</html>

